import fs from "../fs"
import stat from '../util/stat'
import remove from '../remove'
import mkdirs from '../mkdirs'
import pathExists from '../path-exists'
import copy from '../copy'
import path from '../../node/path'
import errorCode from '../../node/error-code'

export default function moveSync (src, dest, opts?) {
    opts = opts || {}
    const overwrite = opts.overwrite || opts.clobber || false

    const { srcStat, isChangingCase = false } = stat.checkPathsSync(src, dest, 'move', opts)
    stat.checkParentPathsSync(src, srcStat, dest, 'move')
    if (!isParentRoot(dest) && !pathExists.pathExistsSync(path.dirname(dest))) mkdirs.mkdirpSync(path.dirname(dest))
    return doRename(src, dest, overwrite, isChangingCase)
}

function isParentRoot (dest) {
    const parent = path.dirname(dest)
    const parsedPath = path.parse(parent)
    return parsedPath.root === parent
}

function doRename (src, dest, overwrite, isChangingCase) {
    if (overwrite) {
        remove.removeSync(dest)
        return rename(src, dest, overwrite)
    }
    if (fs.existsSync(dest)) throw new Error('dest already exists')
    return rename(src, dest, overwrite)
}

function rename (src, dest, overwrite) {
    try {
        fs.renameSync(src, dest)
    } catch (err) {
        if (err.message !== errorCode.errormessage.EXDEV) throw err
        return moveAcrossDevice(src, dest, overwrite)
    }
}

function moveAcrossDevice (src, dest, overwrite) {
    const opts = {
        overwrite,
        errorOnExist: true
    }
    copy.copySync(src, dest, opts);
    return remove.removeSync(src)
}
